package com.flashidea.zddziot.view;

import java.text.DecimalFormat;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.*;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import com.flashidea.zddziot.R;

/**
 * 自定义圆形旋转收音频率调节按钮
 * 
 * @author jinhui
 */
public class RateSeekBarView extends View {

	/**
	 * 圆心坐标
	 */
	private float cx, cy;
	/**
	 * 半径
	 */
	private float radius;
	/**
	 * 旋转点所在位置角度
	 */
	private int angle = 0;
	/**
	 * 刻度值变化回调监听
	 */
	private OnRateChangeListener listener;
	/**
	 * 左边频率值
	 */
	private float minRate = 87;
	/**
	 * 右边边频率值
	 */
	private float maxRate = 108;
	/**
	 * 长刻度线的长度
	 */
	private float longLine = 20;
	/**
	 * 短刻度线的长度
	 */
	private float shortLine = 10;
	/**
	 * 拖动条颜色
	 */
	private int stripColor = Color.WHITE;
	/**
	 * 拖动条大小
	 */
	private float stripSize = 1;
	/**
	 * 刻度线颜色
	 */
	private int rateColor = Color.WHITE;
	/**
	 * 刻度线大小
	 */
	private float rateSize = 1;
	/**
	 * 刻度值字体颜色
	 */
	private int rateTextColor = Color.WHITE;
	/**
	 * 刻度值字体大小
	 */
	private float rateTextSize = 14;
	private float density;

	/**
	 * 设置刻度值字体颜色
	 */
	public void setRateTextColor(int rateTextColor) {
		this.rateTextColor = rateTextColor;
		rotateButtons(0);
	}

	/**
	 * 设置刻度值字体大小
	 */
	public void setRateTextSize(float rateTextSize) {
		this.rateTextSize = rateTextSize;
		rotateButtons(0);
	}

	/**
	 * 设置拖动条的颜色
	 */
	public void setStripColor(int stripColor) {
		this.stripColor = stripColor;
		rotateButtons(0);
	}

	/**
	 * 设置拖动条的大小
	 */
	public void setStripSize(float stripSize) {
		this.stripSize = stripSize * density;
		rotateButtons(0);
	}

	/**
	 * 设置刻度线的颜色
	 */
	public void setRateColor(int rateColor) {
		this.rateColor = rateColor;
		rotateButtons(0);
	}

	/**
	 * 设置刻度线大小
	 */
	public void setRateSize(float rateSize) {
		this.rateSize = rateSize * density;
		rotateButtons(0);
	}

	/**
	 * 设置长刻度线的长度
	 */
	public void setLongLine(float longLine) {
		this.longLine = longLine;
		rotateButtons(0);
	}

	/**
	 * 设置短刻度线的长度
	 */
	public void setShortLine(float shortLine) {
		this.shortLine = shortLine;
		rotateButtons(0);
	}

	/**
	 * 获取最小频率值
	 */
	public float getMinRate() {
		return minRate;
	}

	/**
	 * 设置最小频率值
	 */
	public void setMinRate(float rate) {
		this.minRate = rate;
		rotateButtons(0);
	}

	/**
	 * 获取最大频率值
	 */
	public float getMaxRate() {
		return maxRate;
	}

	/**
	 * 设置最大频率值
	 */
	public void setMaxRate(float rate) {
		this.maxRate = rate;
		rotateButtons(0);
	}

	/**
	 * 设置刻度值变化回调监听
	 * 
	 * @param listener
	 */
	public void setOnRateChangeListener(OnRateChangeListener listener) {
		this.listener = listener;
	}

	/**
	 * 获取角度
	 */
	public int getAngle() {
		return angle;
	}

	/**
	 * 设置角度
	 */
	public void setAngle(int angle) {
		this.angle = angle;
		rotateButtons(0);
	}

	public RateSeekBarView(Context context, AttributeSet attrs, int defStyleAttr) {
		super(context, attrs, defStyleAttr);
		init(context, attrs);
	}

	public RateSeekBarView(Context context, AttributeSet attrs) {
		super(context, attrs);
		init(context, attrs);
	}

	private void init(Context context, AttributeSet attrs) {
		density = getResources().getDisplayMetrics().density;
		/* 这里取得declare-styleable集合 */
		TypedArray typeArray = context.obtainStyledAttributes(attrs, R.styleable.CustomView);
		/* 这里从集合里取出相对应的属性值,第二参数是如果使用者没用配置该属性时所用的默认值 */
		minRate = typeArray.getFloat(R.styleable.CustomView_minRate, 87);
		maxRate = typeArray.getFloat(R.styleable.CustomView_maxRate, 108);
		longLine = typeArray.getDimension(R.styleable.CustomView_longLine, 20);
		shortLine = typeArray.getDimension(R.styleable.CustomView_shortLine, 10);
		stripColor = typeArray.getColor(R.styleable.CustomView_stripColor, Color.WHITE);
		stripSize = typeArray.getDimension(R.styleable.CustomView_stripSize, 1);
		rateColor = typeArray.getColor(R.styleable.CustomView_rateColor, Color.WHITE);
		rateSize = typeArray.getDimension(R.styleable.CustomView_rateSize, 1);
		rateTextColor = typeArray.getColor(R.styleable.CustomView_rateTextColor, Color.WHITE);
		rateTextSize = typeArray.getDimension(R.styleable.CustomView_rateTextSize, 14);
		/* 关闭资源 */
		typeArray.recycle();
		rotateButtons(0);
	}

	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
		int width = MeasureSpec.getSize(getMeasuredWidth());
		// 求圆心在x=(getWidth()/2,0)上，经过(0,0)、(getWidth(),0)的圆半径
		radius = (int) (Math.sqrt(2) * (width / 2f));
		radius = width - radius / 5;
		cx = width / 2f;// 圆心的x坐标
		// 圆心的y坐标
		cy = (float) -Math.sqrt(radius * radius - width / 2 * width / 2);
		setMeasuredDimension(getMeasuredWidth(), (int) (radius + cy + 40));
	}

	@Override
	public void onDraw(Canvas canvas) {
		drawLines(canvas);
		drawPoint(canvas);
		drawCircle(canvas);
	}

	/**
	 * 画拖动条
	 */
	private void drawCircle(Canvas canvas) {
		canvas.save();
		Paint paint = new Paint();
		paint.setColor(stripColor);
		paint.setAntiAlias(true);
		paint.setStrokeWidth(stripSize);
		paint.setStyle(Paint.Style.STROKE);
		canvas.drawCircle(cx, cy, radius, paint);
		canvas.restore();
	}

	/**
	 * 画刻度
	 * 
	 * @param canvas
	 */
	private void drawLines(Canvas canvas) {
		Paint paint = new Paint();
		paint.setColor(rateColor);
		paint.setAntiAlias(true);
		paint.setStrokeWidth(rateSize);
		Path path = new Path();
		canvas.save();
		path.addCircle(cx, cy, radius - shortLine, Path.Direction.CCW);
		canvas.clipPath(path, Region.Op.DIFFERENCE);// 在这之前画的与在这之后画的去交集
		int count = -1;
		for (double i = angle; i < 360 + angle; i += 2) {
			count++;
			if (count % 5 == 0) {
				continue;
			}
			float x = (float) (cx + radius * Math.cos(Math.toRadians(i)));
			float y = (float) (cy + radius * Math.sin(Math.toRadians(i)));
			canvas.drawLine(cx, cy, x, y, paint);
		}
		canvas.restore();
		canvas.save();
		path = new Path();
		path.addCircle(cx, cy, radius - longLine, Path.Direction.CCW);
		canvas.clipPath(path, Region.Op.DIFFERENCE);// 在这之前画的与在这之后画的去交集
		for (double i = angle; i < 360 + angle; i += 10) {
			float x = (float) (cx + radius * Math.cos(Math.toRadians(i)));
			float y = (float) (cy + radius * Math.sin(Math.toRadians(i)));
			canvas.drawLine(cx, cy, x, y, paint);
		}
		canvas.restore();
		paint.setColor(rateTextColor);
		paint.setTextSize(rateTextSize * density);
		count = (int) maxRate;
		for (int i = 87; i <= 108; i++) {
			float x = (float) (cx + radius * Math.cos(Math.toRadians(angle + (i - 87) * 10)));
			float y = (float) (cy + radius * Math.sin(Math.toRadians(angle + (i - 87) * 10)));
			String string = 108 - (i - 87) + "";
			float[] textWidths = new float[string.length()];
			paint.getTextWidths(string, textWidths);
			int textWidth = 0;
			for (float f : textWidths) {
				textWidth += f;
			}
			canvas.save();
			canvas.rotate((float) (computeCurrentAngle(x, y - longLine) - 90), x, y);
			canvas.drawText(string, x - textWidth / 2, y - longLine, paint);
			canvas.restore();
		}
	}

	/**
	 * 画指针
	 * 
	 * @param canvas
	 */
	private void drawPoint(Canvas canvas) {
		Paint paint = new Paint();
		paint.setColor(rateColor);
		paint.setAntiAlias(true);
		Path path = new Path();
		path.moveTo(cx, cy + radius);
		path.lineTo(cx - 8, cy + radius + 20);
		path.lineTo(cx + 8, cy + radius + 20);
		canvas.drawPath(path, paint);
	}

	private double startAngle;

	@Override
	public boolean dispatchTouchEvent(MotionEvent event) {
		super.dispatchTouchEvent(event);
		int x, y;
		if (event.getAction() == MotionEvent.ACTION_DOWN) {
			x = (int) event.getX();
			y = (int) event.getY();
			startAngle = computeCurrentAngle(x, y);
		} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
			x = (int) event.getX();
			y = (int) event.getY();
			if (((x - cx) * (x - cx) + (y - cy) * (y - cy)) > Math.pow(radius + 20, 2)) {
				return false;
			}
			double currentAngle = computeCurrentAngle(x, y);
			rotateButtons(startAngle - currentAngle);
			startAngle = currentAngle;
		} else if (event.getAction() == MotionEvent.ACTION_UP) {
			x = (int) event.getX();
			y = (int) event.getY();
			double currentAngle = computeCurrentAngle(x, y);
			rotateButtons(startAngle - currentAngle);
			startAngle = currentAngle;
		}
		return true;
	}

	/**
	 * 旋转
	 */
	private void rotateButtons(double degree) {
		double x = (angle - degree + 180) % 360;
		if (x > 270 || x < 270 - (maxRate - minRate) * 10) {
			return;
		}
		angle -= degree;
		if (angle < 0) {
			angle += 360;
		} else if (angle >= 360) {
			angle -= 360;
		}
		if (listener != null) {
			listener.onRateChange(this, getId(), getRate());
		}
		Log.i(VIEW_LOG_TAG, getRate() + "");
		invalidate();
	}

	/**
	 * 获得当前刻度值
	 * 
	 * @return
	 */
	public float getRate() {
		float value = Float.parseFloat(new DecimalFormat("#.0").format((angle - 90 + (maxRate - minRate) * 10)
			% 360 / 10f + minRate));
		return value;
	}

	/**
	 * 设置当前刻度值
	 * 
	 * @param value
	 */
	public void setRate(float value) {
		if (value < minRate) {
			value = minRate;
		} else if (value > maxRate) {
			value = maxRate;
		}
		angle = (int) ((value - minRate) * 10f - (maxRate - minRate) * 10f + 90);
		rotateButtons(0);
	}

	/**
	 * 下一个频道
	 */
	public void nextChannel() {
		rotateButtons(-1);
	}

	/**
	 * 上一个频道
	 */
	public void lastChannel() {
		rotateButtons(1);
	}

	/**
	 * 计算某点的角度
	 * 
	 * @param x
	 * @param y
	 */
	private int computeCurrentAngle(float x, float y) {
		float distance = (float) Math.sqrt(((x - cx) * (x - cx) + (y - cy) * (y - cy)));
		int degree = (int) (Math.acos((x - cx) / distance) * 180 / Math.PI);
		if (y < cy) {
			degree = -degree;
		}
		return degree;
	}

	/**
	 * 刻度值变化回调接口
	 * 
	 * @author jinhui
	 */
	public interface OnRateChangeListener {

		/**
		 * 刻度值变化回调接函数
		 * 
		 * @param view
		 * @param viewId
		 * @param value
		 */
		public void onRateChange(Object view, int viewId, float value);
	}
}
